import Compile.CIFA.Token;
import Compile.CIFA.TokenType;
import Compile.CIFA.cifa;
import Compile.YUFA.yufa;
import Compile.YUYI.yuyi;
import Execute.MiniSQL.SqlResult;
import Execute.MiniSQL.TableManager;

import java.util.List;
import java.util.Objects;
import java.util.Scanner;

import static Execute.MiniSQL.TableManager.*;

/*
 * 这是整个编译器的主类
 * 1：提示用户输入语句。
 * 2；进行词法分析、语法分析、语义分析。
 * 3：编译通过后将语句传给Execute。
 * */
public class Main {
    private static boolean cifaflag = true;
    private static boolean yufaflag = true;
    private static boolean yuyiflag = true;

    private static boolean executeflag = true;

    private static boolean state = true;

    public static void startmiDB() throws Exception {
        Scanner sc = new Scanner(System.in);
        String s = null;
        System.out.println("欢迎使用迷你数据库管理系统！请使用help命令查询所有操作介绍");
        for(;;){
            System.out.print("miDB>");
            s = sc.nextLine();
            if (s.equalsIgnoreCase("cifa open")) {
                cifaflag = true;
                recordSystemLogs("开启显示词法分析结果。");
                System.out.println("miDB>开启显示词法分析结果！");
                continue;
            } else if (s.equalsIgnoreCase("yufa open")) {
                yufaflag = true;
                recordSystemLogs("开启显示语法分析结果。");
                System.out.println("miDB>开启显示语法分析结果！");
                continue;
            } else if (s.equalsIgnoreCase("yuyi open")) {
                yuyiflag = true;
                recordSystemLogs("开启显示语义分析结果。");
                System.out.println("miDB>开启显示语义分析结果！");
                continue;
            } else if (s.equalsIgnoreCase("cifa off")) {
                cifaflag = false;
                recordSystemLogs("关闭显示词法分析结果。");
                System.out.println("miDB>关闭显示词法分析结果！");
                continue;
            } else if (s.equalsIgnoreCase("yufa off")) {
                yufaflag = false;
                recordSystemLogs("关闭显示语法分析结果。");
                System.out.println("miDB>关闭显示语法分析结果！");
                continue;
            } else if (s.equalsIgnoreCase("yuyi off")) {
                yuyiflag = false;
                recordSystemLogs("关闭显示语义分析结果。");
                System.out.println("miDB>关闭显示语义分析结果！");
                continue;
            } else if (s.equalsIgnoreCase("execute open")) {
                executeflag = true;
                recordSystemLogs("开启sql执行。");
                System.out.println("miDB>开启sql执行！");
                continue;
            } else if (s.equalsIgnoreCase("execute off")) {
                executeflag = false;
                recordSystemLogs("关闭Sql执行。");
                System.out.println("miDB>关闭Sql执行！");
                continue;
            } else if (s.equalsIgnoreCase("cur setting")) {
                recordSystemLogs("查看当前设置。");
                System.out.println("miDB>当前设置：");
                if (cifaflag) System.out.println("显示词法分析结果");
                else System.out.println("不显示词法分析结果");
                if (yufaflag) System.out.println("显示语法分析结果");
                else System.out.println("不显示语法分析结果");
                if (yuyiflag) System.out.println("显示语义分析结果");
                else System.out.println("不显示语义分析结果");
                if (executeflag) System.out.println("编译运行");
                else System.out.println("仅编译");
                continue;
            }
            // Compile
            int compileResult = startCompile(s);
            if (compileResult == 2) {
                System.out.println("你输入了一行注释！");
            } else if (compileResult == 1) {
                if (executeflag) {
                    Execute(s);
                    if (!state) break;
                }
            } else {
                System.out.println("miDB>编译错误！");
            }

        }
    }

    public static void Execute(String s) {
        System.out.println("---------------------");
        System.out.println("执行结果：");
        SqlResult sqlResult = operate(s);
        try {
            if (sqlResult.getSqlFeedBack().equalsIgnoreCase("quit")) {
                state = false;
            }
        } catch (Exception ignored) {

        }
    }

    public static void showCifaResult(List<Token> tokenList) {
        System.out.println("-----------------------------------");
        System.out.println("词法分析结果");
        for (Token token : tokenList) {
            System.out.println(token.toString());
        }
        System.out.println("-----------------------------------");
    }

    private static void showYufaResult(yufa parser) {
        parser.displayParserTree();
    }

    public static int startCompile(String s) throws Exception {
        // 词法分析
        cifa word = new cifa(s);
        List<Token> tokenList = word.analyze();
        // 查看词法分析结果
        if (cifaflag)
            showCifaResult(tokenList);
        if (!word.flag) {
            // 词法分析错误
            System.out.print("miDB>词法分析错误！");
            System.out.println(tokenList.get(tokenList.size() - 1).toString());
            return -1;
        }
        if (Objects.equals(tokenList.get(0).getType(), TokenType.ANNOTATION)) return 2;
        // 词法分析通过，结果保存在tokenList
        // 语法分析
        yufa parser = new yufa(tokenList);
        String result = parser.getContent();
        if (yufaflag) {
            showYufaResult(parser);
            System.out.println(result);
        }
        if (parser.getFlag()) {
            return -2;
        }
        // 语义分析
        yuyi mean = new yuyi(parser.getRoot());
        String content = mean.getContent();
        if (yuyiflag)
            System.out.println(content);
        if (mean.getFlag()) {
            return -3;
        }
        // 均通过返回1
        return 1;
    }

    public static void main(String[] args) throws Exception {
        // 启动DBMS
        TableManager tableManager = new TableManager();
        startmiDB();
    }
}
